package cs3343.project.family.UI;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import cs3343.project.family.Card;
import cs3343.project.family.CardController;
import cs3343.project.family.Character;
import cs3343.project.family.CharacterController;
import cs3343.project.family.ConfigManager;
import cs3343.project.family.GameController;
import cs3343.project.family.UIController;

/**
 * The Class YesNoFrame.
 */
public class YesNoFrame extends JDialog implements ActionListener {

	/** The content pane. */
	private JPanel contentPane;
	
	/** The gc. */
	private GameController gc;
	
	/** The character controller. */
	private CharacterController characterController;
	
	/** The card controller. */
	private CardController cardController;
	
	/** The ui controller. */
	private UIController uiController;
	
	/** The description panel. */
	private JPanel descriptionPanel;
	
	/** The tool card panel. */
	private JPanel toolCardPanel;
	
	/** The msg panel. */
	private JPanel msgPanel;
	
	/** The button panel. */
	private JPanel buttonPanel;
	
	/** The btn_okay. */
	private JButton btn_okay;
	
	/** The btn_giveup. */
	private JButton btn_giveup;
	
	/** The btn_quit. */
	private JButton btn_quit;
	
	/** The description. */
	private JLabel description;
	
	/** The msg. */
	private JLabel msg;
	
	/** The option. */
	private String[] option;
	
	/** The available card. */
	private JComboBox<String> availableCard;
	
	/** The btn_confirm. */
	private JButton btn_confirm;
	
	/** The current player. */
	private Character currentPlayer;
	
	/** The current card. */
	private Card currentCard;
	
	/** The card type. */
	private String cardType;
	
	/** The card picked. */
	private boolean cardPicked;

	/**
	 * Create the frame.
	 *
	 * @param player the player
	 * @param card the card
	 * @param cardType the card type
	 * @param gc the gc
	 */
	public YesNoFrame(Character player, Card card, String cardType, GameController gc) {
		setModal(true);
		setResizable(false);
		setTitle(ConfigManager.getLangString("YesNoFrameTitle"));
		
		this.gc = gc;
		
		characterController = this.gc.getCharacterController();
		cardController = this.gc.getCardController();
		uiController = this.gc.getUiController();
		initUI();
		
		cardPicked = false;
		
		this.cardType = cardType;
		currentPlayer = player;
		currentCard = card;
		
		descriptionPanel = new JPanel();
		toolCardPanel = new JPanel();
		msgPanel = new JPanel();
		buttonPanel = new JPanel();
		
		btn_quit = new JButton(ConfigManager.getLangString("btnOkay"));
		btn_quit.setVisible(false);
		btn_okay = new JButton(ConfigManager.getLangString("btnDone"));
		btn_giveup = new JButton(ConfigManager.getLangString("btnGiveup"));
		description = new JLabel(card.getDescription());
		msg = new JLabel("", JLabel.CENTER);
		Font f = new Font("Dialog", Font.PLAIN, 20);
	    msg.setFont(f);
		
		option = currentPlayer.getAvailableCards(cardType, cardController);
		availableCard = new JComboBox(option);
		btn_confirm = new JButton(ConfigManager.getLangString("btnConfirmUseCard"));
	    
	    descriptionPanel.setLayout(new BorderLayout());
	    toolCardPanel.setLayout(new BorderLayout());
		buttonPanel.setLayout(new GridLayout(1, 2));
		
		getContentPane().add(buttonPanel, BorderLayout.SOUTH);
		getContentPane().add(msgPanel, BorderLayout.CENTER);
		getContentPane().add(descriptionPanel, BorderLayout.NORTH);
		
		descriptionPanel.add(description, BorderLayout.NORTH);
		descriptionPanel.add(toolCardPanel, BorderLayout.CENTER);
		

		toolCardPanel.add(new JLabel(" "), BorderLayout.NORTH);
		toolCardPanel.add(availableCard, BorderLayout.CENTER);
		toolCardPanel.add(btn_confirm, BorderLayout.SOUTH);
		
		msgPanel.add(msg);
		msgPanel.add(btn_quit);
		
		buttonPanel.add(btn_okay);
		buttonPanel.add(btn_giveup);
		activateToolCardButton();
		
		btn_confirm.addActionListener(this);
		btn_okay.addActionListener(this);
		btn_giveup.addActionListener(this);
		btn_quit.addActionListener(this);
		//contentPane.add(cardPanel);
		
		//UIController.frameCentering(this);
	}
	
	/**
	 * Inits the ui.
	 */
	private void initUI() {
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setBounds(500, 350, 450, 220);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
	}
	
	/**
	 * Activate tool card button.
	 */
	private void activateToolCardButton() {
		if (option[0].equalsIgnoreCase(ConfigManager.getLangString("msgNoCardOption")))
			btn_confirm.setEnabled(false);
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		//a card picked
		if (e.getSource() == btn_confirm) {
			if (!option[0].equalsIgnoreCase(ConfigManager.getLangString("msgNoCardOption")))
				if ((String) availableCard.getSelectedItem() != ConfigManager.getLangString("msgCardOption")) {
					cardPicked = true;
					availableCard.setEnabled(false);
					btn_confirm.setEnabled(false);
					//loop which card is selected and apply corresponding function
					cardApplication();
				}
    	}
		//short cut button to quit frame with no change to esteem-point
		else if (e.getSource() == btn_quit)
			disposeAndNext();			

		//if no card is selected, run normal process
		buttonEffect(e, cardPicked);
    }
	
	/**
	 * Button effect.
	 *
	 * @param e the e
	 * @param cardPicked the card picked
	 */
	public void buttonEffect(ActionEvent e, boolean cardPicked) {

    	if (e.getSource() == btn_okay) {
    		
    		if (cardPicked) {
				for (int i = 1; i <= cardController.getNumOfMagicToolCard(); i++) {
					if ((String) availableCard.getSelectedItem() == cardController.getMagicToolCard(String.valueOf(i)).getDescription()) {
						switch (i) {
							case 5: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard5(e); break;
							case 6: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard6(e); break;
							case 11: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard11(50); break;
						}
					}
				}
    		}
    		else {
    			//for sister function
    			gc.getRoleController().sisRoleFunction();
    			int oriEsteem = currentPlayer.getEsteem(); 
				gc.updateEsteem(currentPlayer, oriEsteem += 50, "完成行動卡或說話卡");
				disposeAndNext();
    		}
		}    	
    	else if (e.getSource() == btn_giveup) {

    		if (cardPicked) {
				for (int i = 1; i <= cardController.getNumOfMagicToolCard(); i++) {
					if ((String) availableCard.getSelectedItem() == cardController.getMagicToolCard(String.valueOf(i)).getDescription()){
						switch (i) {
							case 5: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard5(e); break;
							case 6: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard6(e); break;
							case 11: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard11(-50); break;
						}
					}
				}
    		}
    		else {
    			int oriEsteem = currentPlayer.getEsteem(); 
				gc.updateEsteem(currentPlayer, oriEsteem -= 50, "放棄或未能完成行動卡或說話卡");
				disposeAndNext();
    		}
		}
    	
    	for (int i = 0; i < characterController.getNumOfPlayer(); i++)
    		gc.getUiController().getGameFrame().setPlayerEsteemLabel(i);
	}
	
	
	/**
	 * Card application.
	 */
	public void cardApplication() {
		for (int i = 1; i <= cardController.getNumOfMagicToolCard(); i++) {
			if ((String) availableCard.getSelectedItem() == cardController.getMagicToolCard(String.valueOf(i)).getDescription()) {
				switch (i) {
					case 1: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard1_3_4(); break;
					case 3: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard1_3_4(); break;
					case 4: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard1_3_4(); break;
					case 7: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard7(cardType); break;
					case 8: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard8(); break;
				}
			}
		}
	}
	
	//tool card function
	
	//1	[說話]	工具卡	免一次說話。
	//3	[動作]	工具卡	免一次動作。
	//4	[說話/事件/動作]	工具卡	免一次說話/事件/動作。
	/**
	 * Tool card1_3_4.
	 */
	public void toolCard1_3_4() {
		disableButtons();
		msg.setText(ConfigManager.getLangString("msgSkipCard"));
	}
	
	//5	[說話/事件/動作]	保護罩	可保護使用者即使無法完成任務也不用扣自尊值。
	/**
	 * Tool card5.
	 *
	 * @param e the e
	 */
	public void toolCard5(ActionEvent e) {
		if(e.getSource() == btn_giveup) {
			disableButtons();
			msg.setText(ConfigManager.getLangString("msgNoPenalty"));
		}
		else {
	    	msg.setText(ConfigManager.getLangString("msgUpdateEsteem") + "+50");
	    	int oriEsteem = currentPlayer.getEsteem();
	    	gc.updateEsteem(currentPlayer, oriEsteem += 50, "使用工作卡5");
	    	disableButtons();
		}
	}
	
	//6	[說話/事件/動作]	工具卡	當遇到事件卡，如完成任務可獲得雙倍自尊值，無法完成任務不扣自尊值。
	/**
	 * Tool card6.
	 *
	 * @param e the e
	 */
	public void toolCard6(ActionEvent e) {
		if (e.getSource() == btn_giveup) {
	    	msg.setText(ConfigManager.getLangString("msgNoPenalty"));
	    	disableButtons();
		}
		else {
	    	msg.setText(ConfigManager.getLangString("msgUpdateEsteem") + "+100");
	    	int oriEsteem = currentPlayer.getEsteem();
	    	gc.updateEsteem(currentPlayer, oriEsteem += 50 * 2, "使用工作卡6");
	    	disableButtons();
		}
	}
	
	//7	[說話/事件/動作]	工具卡	當遇到說話/事件/動作卡，可放棄該卡，再抽一次同類型的卡。
	/**
	 * Tool card7.
	 *
	 * @param cardType the card type
	 */
	public void toolCard7(String cardType) {
		int ranCard = 0;
		Card card = null;
		
		if (cardType == "ActionCard") {
			ranCard = (int) (cardController.getNumOfActionCard() * Math.random() + 1);
			card = cardController.getActionCard(String.valueOf(ranCard));
		}
		else if (cardType == "OralCard") {
			ranCard = (int) (cardController.getNumOfOralCard() * Math.random() + 1);
			card = cardController.getOralCard(String.valueOf(ranCard));
		}

		uiController.showYesNoFrame(card, currentPlayer, cardType);
		this.setVisible(false);
	}
	
	/**
	 * Tool card8.
	 */
	public void toolCard8() {
	    Character selectedPlayer = gc.selectCharacter(ConfigManager.getLangString("msgChoosePlayerTitle"), ConfigManager.getLangString("msgChoosePlayer"));
		currentPlayer = selectedPlayer;
	    cardPicked = false;
	}
	
	//11	[說話/事件/動作]	合作卡	所有家庭成員都會受到獎/罰。
	/**
	 * Tool card11.
	 *
	 * @param esteem the esteem
	 */
	public void toolCard11(int esteem) {
			for (int i = 0; i < characterController.getNumOfPlayer(); i++) {
				int oriEsteem = characterController.getPlayer(i).getEsteem();
				gc.updateEsteem(characterController.getPlayer(i), oriEsteem += esteem, "使用工作卡11");
			}
			
			if (esteem > 0)
				msg.setText(ConfigManager.getLangString("msgUpdateAllEsteem") + esteem);
			else
				msg.setText(ConfigManager.getLangString("msgUpdateAllEsteem") + esteem);
			
			disableButtons();
	}
	
	/**
	 * Disable buttons.
	 */
	public void disableButtons() {
		btn_okay.setEnabled(false);
		btn_giveup.setEnabled(false);
		btn_quit.setVisible(true);
	}
	
	/**
	 * Gets the available card.
	 *
	 * @return the available card
	 */
	public JComboBox<String> getAvailableCard() {
		return this.availableCard;
	}

	/**
	 * Gets the btn_confirm.
	 *
	 * @return the btn_confirm
	 */
	public JButton getBtn_confirm() {
		return this.btn_confirm;
	}

	/**
	 * Gets the btn_okay.
	 *
	 * @return the btn_okay
	 */
	public JButton getBtn_okay() {
		return this.btn_okay;
	}
	
	/**
	 * Gets the btn_giveup.
	 *
	 * @return the btn_giveup
	 */
	public JButton getBtn_giveup() {
		return this.btn_giveup;
	}
	
	/**
	 * Dispose and next.
	 */
	public void disposeAndNext() {
		this.dispose();
		gc.afterPressed();
	}
}
